/* 作者：方块君(原作:flyAkari)
   本代码适用于ESP8266 NodeMCU + 12864显示屏
  7pin SPI引脚，正面看，从左到右依次为GND、VCC、D0、D1、RES、DC、CS
   ESP8266 ---  OLED
     3V    ---  VCC
     G     ---  GND
     D7    ---  D1
     D5    ---  D0
     D2orD8---  CS
     D1    ---  DC
     RST   ---  RES

  4pin IIC引脚，正面看，从左到右依次为GND、VCC、SCL、SDA
     OLED  ---  ESP8266
     VCC   ---  3.3V
     GND   ---  G (GND)
     SCL   ---  D1(GPIO5)
     SDA   ---  D2(GPIO4)
*/

#include <U8g2lib.h>

U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/U8X8_PIN_NONE);
//U8G2_SSD1306_128X64_NONAME_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 4, /* dc=*/ 5, /* reset=*/ 3); //使用7个引脚SPI屏幕的取消注释这行并注释掉上一行
char tcpu[25], scpuuti[25], scpuclk[25], cs[25], vcpu[25], wd[25], tq[25], page[25], memory[25], tim[25], mobo[25], gpuclk[25], cfan[25], gfan[25], gutil[25], gm[25], fans[25];
char id[15];
char value[25];
byte inByte;
//void drawWeatherSymbol(u8g2_uint_t x, u8g2_uint_t y, uint8_t symbol);
#define SUN_DAY 0
#define SUN_NIGHT 1
#define SUN_CLOUD 2
#define CLOUD 3
#define RAIN 4
#define THUNDER 5

void refresh()
{
  u8g2.clearBuffer();                         // 清空显存
  u8g2.setFont(u8g2_font_unifont_t_chinese2); // 选一个合适的字体
  if (strcmp("a", page) == 0) {
    u8g2.drawStr(8, 10, tim);

    u8g2.drawStr(0, 30, "CPU Temp:");
    u8g2.drawStr(73, 30, tcpu);
    u8g2.drawStr(105, 30, "'C");

    u8g2.drawStr(0, 45, "CPU Util:");
    u8g2.drawStr(73, 45, scpuuti);
    u8g2.drawStr(105, 45, "%");

    u8g2.drawStr(0, 60, "CPU Freq:");
    u8g2.drawStr(73, 60, scpuclk);
    u8g2.drawStr(105, 60, "GHz");
    u8g2.sendBuffer(); // 打到屏幕上
  } else if (strcmp("b", page) == 0) {
    u8g2.drawStr(8, 10, tim);

    u8g2.drawStr(0, 30, "CPU Volt:");
    u8g2.drawStr(73, 30, vcpu);
    u8g2.drawStr(105, 30, "V");

    u8g2.drawStr(0, 45, "MOBO Temp:");
    u8g2.drawStr(80, 45, mobo);
    u8g2.drawStr(105, 45, "'C");

    u8g2.drawStr(0, 60, "GPU Volt:");
    u8g2.drawStr(73, 60, gpuclk);
    u8g2.drawStr(105, 60, "V");
    u8g2.sendBuffer(); // 打到屏幕上
  } else if (strcmp("c", page) == 0) {
    u8g2.drawStr(8, 10, tim);

    u8g2.drawStr(0, 30, "CPU Fan:");
    u8g2.drawStr(65, 30, cfan);
    u8g2.drawStr(105, 30, "RPM");

    u8g2.drawStr(0, 45, "GPU Fan:");
    u8g2.drawStr(73, 45, gfan);
    u8g2.drawStr(105, 45, "%");

    u8g2.drawStr(0, 60, "Memory:");
    u8g2.drawStr(73, 60, memory);
    u8g2.drawStr(105, 60, "V");
    u8g2.sendBuffer(); // 打到屏幕上
  } else if (strcmp("d", page) == 0) {
    u8g2.drawStr(8, 10, tim);

    u8g2.drawStr(0, 30, "GPU Util:");
    u8g2.drawStr(73, 30, gutil);
    u8g2.drawStr(105, 30, "%");

    u8g2.drawStr(0, 45, "GPU Memory:");
    u8g2.drawStr(85, 45, gm);
    u8g2.drawStr(105, 45, "%");

    u8g2.drawStr(0, 60, "Bili Fans:");
    u8g2.drawStr(80, 60, fans);
    u8g2.sendBuffer(); // 打到屏幕上
  } else if (strcmp("e", page) == 0) {
    if (strcmp("ty", tq) == 0) {
      drawWeatherSymbol(0, 48, SUN_DAY);
    } else if (strcmp("qzdy", tq) == 0) {
      drawWeatherSymbol(0, 48, SUN_CLOUD);
    } else if (strcmp("dy", tq) == 0) {
      drawWeatherSymbol(0, 48, CLOUD);
    } else if (strcmp("xy", tq) == 0) {
      drawWeatherSymbol(0, 48, RAIN);
    } else if (strcmp("dl", tq) == 0) {
      drawWeatherSymbol(0, 48, THUNDER);
    }
    u8g2.setFont(u8g2_font_logisoso32_tf);
    u8g2.setCursor(48 + 3, 42);
    u8g2.print(wd);
    u8g2.print("°C");   // requires enableUTF8Print()
    u8g2.setFont(u8g2_font_unifont_t_chinese3);
    u8g2_uint_t strWidth = u8g2.getUTF8Width(cs);
    u8g2_uint_t displayWidth = u8g2.getDisplayWidth();
    u8g2.setCursor(displayWidth - strWidth - 5, 60);
    u8g2.print(cs);
    u8g2.sendBuffer();
  } else if (strcmp("f", page) == 0) {
    if (strcmp("ty", tq) == 0) {
      drawWeatherSymbol(0, 48, SUN_DAY);
    } else if (strcmp("qzdy", tq) == 0) {
      drawWeatherSymbol(0, 48, SUN_CLOUD);
    } else if (strcmp("dy", tq) == 0) {
      drawWeatherSymbol(0, 48, CLOUD);
    } else if (strcmp("xy", tq) == 0) {
      drawWeatherSymbol(0, 48, RAIN);
    } else if (strcmp("dl", tq) == 0) {
      drawWeatherSymbol(0, 48, THUNDER);
    }
    u8g2.setFont(u8g2_font_logisoso32_tf);
    u8g2.setCursor(48 + 3, 42);
    u8g2.print(wd);
    u8g2.print("°C");   // requires enableUTF8Print()
    u8g2.setFont(u8g2_font_unifont_t_chinese3);
    u8g2_uint_t strWidth = u8g2.getUTF8Width(cs);
    u8g2_uint_t displayWidth = u8g2.getDisplayWidth();
    u8g2.setCursor(displayWidth - strWidth - 5, 60);
    u8g2.print(cs);
    u8g2.sendBuffer();
  } else {
    Serial.println(page);
    u8g2.setFont(u8g2_font_unifont_t_chinese2); // 选一个合适的字体
    u8g2.drawStr(30, 35, "type error!");
    u8g2.sendBuffer(); // 打到屏幕上
  }

}

void setup()
{
  // put your setup code here, to run once:
  u8g2.begin();
  u8g2.enableUTF8Print(); //开启后能显示一些中文字
  Serial.begin(1500000);
  u8g2.clearBuffer();                         // 清空显存
  u8g2.setFont(u8g2_font_unifont_t_chinese2); // 选一个合适的字体
  u8g2.drawStr(25, 35, "Loading.....");
  u8g2.sendBuffer(); // 打到屏幕上
}

void loop()
{
  if (Serial.available() > 0)
  { //数据帧格式：?TCPU=37!
    inByte = Serial.read();
    if (inByte == '?')
    {
      int i = 0;
      while (inByte != '=')
      {
        while (Serial.available() == 0)
          ;
        inByte = Serial.read();
        if (inByte != '=')
        {
          id[i++] = inByte;
        }
        else
        {
          id[i] = '\0';
        }
      }
      i = 0;
      while (inByte != '!')
      {
        while (Serial.available() == 0)
          ;
        inByte = Serial.read();
        if (inByte != '!')
        {
          value[i++] = inByte;
        }
        else
        {
          value[i] = '\0';
        }
      }
      i = 0;
      Serial.println(id); //如果需要显示其他的信息，去上位机输出里查名称
      Serial.println(value);
      if (strcmp("TCPU", id) == 0)
        strcpy(tcpu, value);
      if (strcmp("SCPUUTI", id) == 0)
        strcpy(scpuuti, value);
      if (strcmp("SCPUCLK", id) == 0)
        strcpy(scpuclk, value);
      if (strcmp("VCPU", id) == 0)
        strcpy(vcpu, value);
      if (strcmp("MEMORY", id) == 0)
        strcpy(memory, value);
      if (strcmp("TIM", id) == 0)
        strcpy(tim, value);
      if (strcmp("MOBO", id) == 0)
        strcpy(mobo, value);
      if (strcmp("VGPU", id) == 0)
        strcpy(gpuclk, value);
      if (strcmp("CFAN", id) == 0)
        strcpy(cfan, value);
      if (strcmp("GFAN", id) == 0)
        strcpy(gfan, value);
      if (strcmp("GUTIL", id) == 0)
        strcpy(gutil, value);
      if (strcmp("GM", id) == 0)
        strcpy(gm, value);
      if (strcmp("FANS", id) == 0)
        strcpy(fans, value);
      if (strcmp("PAGE", id) == 0)
        strcpy(page, value);
      if (strcmp("TQ", id) == 0)
        strcpy(tq, value);
      if (strcmp("WD", id) == 0)
        strcpy(wd, value);
      if (strcmp("CS", id) == 0)
        strcpy(cs, value);
      refresh();
    } else {
      u8g2.clearBuffer();                         // 清空显存
      u8g2.setFont(u8g2_font_unifont_t_chinese2); // 选一个合适的字体
      u8g2.drawStr(35, 35, "data error!");
      u8g2.sendBuffer(); // 打到屏幕上
    }
  }
}

void drawWeatherSymbol(u8g2_uint_t x, u8g2_uint_t y, uint8_t symbol)
{
  // fonts used:
  // u8g2_font_open_iconic_embedded_6x_t
  // u8g2_font_open_iconic_weather_6x_t
  // encoding values, see: https://github.com/olikraus/u8g2/wiki/fntgrpiconic
  switch (symbol)
  {
    case SUN_DAY://太阳
      u8g2.setFont(u8g2_font_open_iconic_weather_6x_t);
      u8g2.drawGlyph(x, y, 69);
      break;
    case SUN_NIGHT://太阳
      u8g2.setFont(u8g2_font_open_iconic_weather_6x_t);
      u8g2.drawGlyph(x, y, 66);
      break;
    case SUN_CLOUD://晴间多云
      u8g2.setFont(u8g2_font_open_iconic_weather_6x_t);
      u8g2.drawGlyph(x, y, 65);
      break;
    case CLOUD://多云
      u8g2.setFont(u8g2_font_open_iconic_weather_6x_t);
      u8g2.drawGlyph(x, y, 64);
      break;
    case RAIN://下雨
      u8g2.setFont(u8g2_font_open_iconic_weather_6x_t);
      u8g2.drawGlyph(x, y, 67);
      break;
    case THUNDER://打雷
      u8g2.setFont(u8g2_font_open_iconic_embedded_6x_t);
      u8g2.drawGlyph(x, y, 67);
      break;
  }
}
